package gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 * @author Gavin Greene
 * @author Daniel Dalton
 * 
 * This GUI consists of the frame, Text fields, Menu, and Action Listeners, 
 * The events and data are sent to observer classes.
 * Various nastygrams in the form of error messages are generated 
 * when something goes against the contract of an item.
 * @author
 */
public class gui extends Observable implements Observer{
	private static final String SEPERATOR = "===================================";
	//private static String[] entry_form_kw_history = {"test", "","", "", "", "", "", "", "", ""};
	private static List<String> entry_form_kw_history;
	/**
	 * 
	 */
	private static final String ENTRY_FORM_CLASSNAME = entryForm.class.getName();
	/**
	 * The main frame
	 */
	private JFrame my_frame;
	
	/**
	 * The menu bar declared as in innerclass at the bottom.
	 */
	private MenuBar my_menu;

	/**
	 * The text field where the data will be written to, this has mutators.
	 */
	private JTextArea my_text_field;

	

	private boolean my_debug_flag;
	
	/**
	 *  for benchmarking mode
	 */
	private boolean my_benchmark_flag;
	
	

	/**
	 * The constructor for the GUI class creates the GUI itself, the frame, a menu, 
	 *  and the appropriate action listeners. 
	 */
	public gui(){
		super();

		my_frame = new JFrame();

		my_menu = new MenuBar();

		my_frame.add(my_menu, BorderLayout.NORTH);

		my_text_field = new JTextArea();

		
		setupTextField(my_text_field);
		
		JScrollPane scroll = new JScrollPane(my_text_field);
		//scroll.setPreferredScrollableViewportSize();
		JScrollBar bar = new JScrollBar();
		
		scroll.setVerticalScrollBar(bar);
		scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

		my_frame.getContentPane().add(scroll);
		my_frame.setPreferredSize(new Dimension(500,500));
		
		entry_form_kw_history = new LinkedList<String>();
		setupFrame(my_frame);
	}

	/**
	 * Sets the default behavior for the frame.
	 * @param the_frame
	 */
	private void setupFrame(JFrame the_frame){

		the_frame.setTitle("Web Crawler - TCSS 422");
		the_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		the_frame.pack();
		the_frame.setVisible(true);
	}

	private void setupTextField(JTextArea the_text_field){
		the_text_field.setEditable(false);
		the_text_field.setWrapStyleWord(true);
		//the_text_field.setPreferredSize(new Dimension(450, 200));
		the_text_field.setText("Welcome to webcrawler" + "\n" +
		"To enter a URL choose: File->Open Url");
	}

	public void WriteTextField(String[] the_text){
		for(String item : the_text){
			WriteTextField(the_text);
		}
		
	}
	/**
	 * Appends the text sent in to the text field.
	 * @param the_text the text to write.
	 */
	public void WriteTextField(String the_text){
		my_text_field.append(the_text + "\n");
		//my_text_field.setPreferredSize(preferredSize)

	}
	
	public void WriteSeperator(){
		WriteTextField(SEPERATOR);
	}
	/**
	 * This is for when we don't want a space
	 * @param the_text
	 */
	public void AppendTextField(String the_text){
		my_text_field.append(the_text);
	}
	/**
	 * Clears the text field.
	 */
	public void ClearTextField(){
		my_text_field.setText("");
	}

	/**
	 * prompts the user to select a url (via jdialouge) 
	 * NO LONGER USERD
	
	private void selectUrl(){
		String s = JOptionPane.showInputDialog("Please enter a url");
		this.setChanged();
		notifyObservers(s);
		//the user hit cancel
	}
	 */

	/* Getters and Setters */


	public boolean getDebugModeFlag(){
		return my_debug_flag;
	}
	
	public void setDebugFlag(boolean yes_no){
		my_debug_flag = yes_no;
	}

	
	public boolean getBenchmarkFlag(){
		return my_benchmark_flag;
	}
	
	public void setBenchmarkFlag(boolean yes_no){
		my_benchmark_flag = yes_no;
	}
	
	
	
	
	
	private void createEntryForm(List<String> word_history){
		entryForm e = new entryForm(word_history);
		e.addObserver(this);
	}
	//Inner class for Menu
	/**
	 * Created for TCSS 422
	 * The menu bar includes menu buttons and action Listners that do various (non-suprising) things.
	 * This was done as an innerclass because it is so tightly coupled with the GUI class.
	 * 
	 * There is also an about bar, that gives some information about the programmers.
	 */
	public class MenuBar extends JMenuBar{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;


		MenuBar()
		{
			super();
			JMenu fileMenu = new JMenu("File");
			JMenu settingsMenu = new JMenu("Settings");
			JMenu helpMenu = new JMenu("Help");
			

			SetupFileMenu(fileMenu);
			this.add(fileMenu);
			
			SetupSettingsMenu(settingsMenu);
			this.add(settingsMenu);
			
			SetupHelpMenu(helpMenu);
			this.add(helpMenu);
		}

		private void SetupFileMenu(JMenu file_menu){

			JMenuItem menuOpen = new JMenuItem("Open URL");
			menuOpen.setMnemonic('o');
			menuOpen.addActionListener(new ActionListener()
			{
				@Override
				public void actionPerformed(ActionEvent arg0) {
					//selectUrl();
					createEntryForm(entry_form_kw_history);
				}
			});

			//the user hit cancel

			JMenuItem menuQuit = new JMenuItem("Quit");
			menuQuit.setMnemonic('q');
			menuQuit.addActionListener(new ActionListener()
			{
				@Override
				public void actionPerformed(ActionEvent arg0) {
					System.exit(0);
				}
			});
			file_menu.add(menuOpen);
			file_menu.addSeparator();
			file_menu.add(menuQuit);

		}
		
		//TODO add handlers for Settings Menu
		private void SetupSettingsMenu(JMenu settings_menu){
			
			
			//threadding checkbox handler

				
			final JCheckBoxMenuItem menuDebug = new JCheckBoxMenuItem("Debug Mode");
			menuDebug.setMnemonic('d');
			//debug checkbox handler
			menuDebug.addActionListener(new ActionListener()
			{
				@Override
				public void actionPerformed(ActionEvent arg0) {
					Boolean isChecked = menuDebug.getState();
					if(isChecked){
						setDebugFlag(true);
						//System.out.println("Debug Mode Enabled");
					}
					else{
						setDebugFlag(false);
						//System.out.println("Debug Mode Disabled");
					}
				}
			});
			settings_menu.add(menuDebug);
		
		final JCheckBoxMenuItem menuBenchmark = new JCheckBoxMenuItem("Benchmark Mode");
		menuBenchmark.setMnemonic('b');
		//debug checkbox handler
		menuBenchmark.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0) {
				Boolean isChecked = menuBenchmark.getState();
				if(isChecked){
					setBenchmarkFlag(true);
					//System.out.println("benchmark Mode Enabled");
				}
				else{
					setBenchmarkFlag(false);
					//System.out.println("Debug Mode Disabled");
				}
			}
		});
		settings_menu.add(menuBenchmark);
		
	}
	
		
		
		
		private void SetupHelpMenu(JMenu help_menu){

			JMenuItem menuAbout = new JMenuItem("About");
			menuAbout.setMnemonic('a');
			menuAbout.addActionListener(new ActionListener()
			{
				@Override
				public void actionPerformed(ActionEvent arg0) {
					JOptionPane.showMessageDialog(null,
							"Made for TCSS 422 by:" + "\n" +
							"Gavin Greene" + "\n" +
							"Dan Dalton");

				}
			});
			help_menu.add(menuAbout);
		}

	}

	/**
	 * This handles ifno that is coming in from the entryForm
	 */
	@Override
	public void update(Observable o, Object arg) {
		if(o.getClass().getName() == ENTRY_FORM_CLASSNAME){
			//we save the history...
			//Map<String, Object> data = (Map<String, Object>) arg;
			data.Request data = (data.Request)arg;
			//we want to tell java that we are indeed passing a string array
			List<String> kwords = data.getKeywords();
			
			entry_form_kw_history = kwords;
			// and pass it along; it's okay if it's from our class
			setChanged();
			notifyObservers(arg);
		}
		else{
			//what are we doing here !?!
		}
	}
}
